# intent_agent.py
import re
from typing import Dict, Tuple
from scenario_knowledge import SCENARIO_KNOWLEDGE


class IntentRecognizer:
    def __init__(self):
        self.scenarios = SCENARIO_KNOWLEDGE
        # 预编译关键词正则表达式
        self.keyword_patterns = {
            scenario: re.compile(
                '|'.join(
                    re.escape(keyword)
                    for keyword in data['keywords']
                ),
                re.IGNORECASE
            )
            for scenario, data in self.scenarios.items()
            if data['keywords']
        }

    def recognize_intent(self, user_input: str) -> Tuple[str, float]:
        """
        识别用户意图并返回最可能的场景及其置信度

        参数:
            user_input: 用户输入的自然语言文本

        返回:
            tuple: (场景ID, 置信度0-1)
        """
        # 转换为小写便于匹配
        input_lower = user_input.lower()

        # 计算每个场景的匹配分数
        scores = {}
        for scenario, data in self.scenarios.items():
            score = 0

            # 关键词匹配
            if scenario in self.keyword_patterns:
                matches = len(self.keyword_patterns[scenario].findall(input_lower))
                score += matches * 0.3  # 每个关键词匹配增加0.3分

            # 示例相似度 (简化版，实际可以使用更复杂的相似度算法)
            for example in data['examples']:
                if example.lower() in input_lower or input_lower in example.lower():
                    score += 0.5

            scores[scenario] = score

        # 处理混合场景
        business_scores = sum(
            scores[scenario]
            for scenario in ['new_customer', 'existing_customer', 'high_value']
        )
        if business_scores >= 1.5 and len([
            s for s in ['new_customer', 'existing_customer', 'high_value']
            if scores[s] > 0
        ]) >= 2:
            scores['mixed'] = business_scores * 0.8  # 混合场景得分

        # 如果没有匹配到任何业务场景，则归为日常对话
        if all(scores[scenario] < 0.5 for scenario in [
            'new_customer', 'existing_customer', 'high_value', 'mixed'
        ]):
            scores['daily_conversation'] += 1.0  # 增加日常对话得分

        # 找到得分最高的场景
        best_scenario = max(scores.items(), key=lambda x: x[1])

        # 计算置信度 (归一化到0-1)
        total_score = sum(scores.values())
        confidence = best_scenario[1] / total_score if total_score > 0 else 0

        return best_scenario[0], round(confidence, 2)

    def explain_decision(self, user_input: str) -> Dict:
        """
        提供意图识别的解释信息

        参数:
            user_input: 用户输入的自然语言文本

        返回:
            dict: 包含识别结果和详细解释的信息
        """
        scenario, confidence = self.recognize_intent(user_input)
        explanation = {
            "input": user_input,
            "recognized_scenario": scenario,
            "scenario_name": self.scenarios[scenario]['name'],
            "confidence": confidence,
            "matched_keywords": [],
            "similar_examples": []
        }

        # 找出匹配的关键词
        if scenario in self.keyword_patterns:
            explanation['matched_keywords'] = list(set(
                match.lower()
                for match in self.keyword_patterns[scenario].findall(user_input.lower())
            ))

        # 找出相似的示例
        input_lower = user_input.lower()
        for example in self.scenarios[scenario]['examples']:
            if example.lower() in input_lower or input_lower in example.lower():
                explanation['similar_examples'].append(example)
                if len(explanation['similar_examples']) >= 3:  # 最多显示3个相似示例
                    break

        return explanation
